//contains all function for using USART 1/2/3

#include "interface_usart.h"



/**
Constructor of class ConnectionUSART
*/
ConnectionUSART::ConnectionUSART(uint8_t USARTPort, uint16_t BaudRate)
{
	if(USARTPort > 3) //check for coorect port, if not set to port 1 (=USART1)
	{
		Port = 1;
	}


	Port = USARTPort;
	USARTInit(BaudRate, Port);
}
/*----------------------------------------------------------------------------------*/


/**
USART init function
*/
void ConnectionUSART::USARTInit(uint16_t BRate, uint8_t USART)
{
	//GPIO Configuration
	USART_InitTypeDef USART_InitStructure;
	USART_ClockInitTypeDef USART_ClockInitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;

	switch(USART)
	{
		 case 1:{
//							//enable bus clocks
//							RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_AHB1Periph_GPIOA, ENABLE);
//							GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;		//Tx		
//							GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
//							GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//							GPIO_Init(GPIOA, &GPIO_InitStructure);
//							GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;	//Rx
//							GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//							GPIO_Init(GPIOA, &GPIO_InitStructure);		
						}break;	
			case 2:

				//enable bus clocks
				RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
				RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
				
				GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
				GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);

			
				GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;			//Tx		
				GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
				GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
				GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
				GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
				GPIO_Init(GPIOA, &GPIO_InitStructure);
			
        /* Configure USART2 Rx (PA3) as input floating */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
        GPIO_Init(GPIOA, &GPIO_InitStructure );
			

				break;
			case 3:
				/*			
				//enable bus clocks
							RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3 | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
							GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;	//Tx			
							GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
							GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
							GPIO_Init(GPIOB, &GPIO_InitStructure); 			//Rx
							GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
							GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
							GPIO_Init(GPIOB, &GPIO_InitStructure);		
						}break;
				*/
	}

	

	
	
	USART_InitStructure.USART_BaudRate = BRate;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No ;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

		switch(USART)
	{
		case 1:{
						USART_Init(USART1, &USART_InitStructure);
						USART_Cmd(USART1, ENABLE);
					}break;
		case 2:{
						USART_Init(USART2, &USART_InitStructure);
						USART_Cmd(USART2, ENABLE);
					}break;
		case 3:{
						USART_Init(USART3, &USART_InitStructure);
						USART_Cmd(USART3, ENABLE);
					}break;
	}
	
}
/*----------------------------------------------------------------------------------*/


/**
Function sends an simple byte over UART
*/
void ConnectionUSART::Put(uint8_t ch)
{
	switch(Port)
	{
		case 1:
		{
      USART_SendData(USART1, (uint8_t) ch);
      //Loop until the end of transmission
      while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
      {
      }
		}break;
		case 2:
		{
      USART_SendData(USART2, (uint8_t) ch);
      //Loop until the end of transmission
      while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
      {
      }
		}break;
		case 3:
		{
      USART_SendData(USART3, (uint8_t) ch);
      //Loop until the end of transmission
      while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET)
      {
      }
		}break;
	}
}
/*----------------------------------------------------------------------------------*/


/**
sends integer based data over USART
*/
void ConnectionUSART::SendData(int value)
{
		int i = 0;
		int j;
		unsigned int nr_digits = 0;
		char buffer[25];
		for(j = 0;j<=25;j++)
		{
			buffer[j] = 0;
		}
		
		if (value < 0) {
		this->Put('-');
		value = value * -1;
		}
		

		while (value > 0) {
		buffer[nr_digits++] = "0123456789"[value % 10];
		value /= 10;
		}
		
		for (i = nr_digits; i >= 0; i--)
		this->Put(buffer[i]);

		this->Put('\n');
}
/*----------------------------------------------------------------------------------*/


/**
Reading an simple byte over UART
*/
uint8_t ConnectionUSART::Get(void)
{

	switch(Port)
	{
		case 1:{
					     while ( USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
						      return (uint8_t)USART_ReceiveData(USART1);
						}
		case 2:{
					     while ( USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET);
						      return (uint8_t)USART_ReceiveData(USART2);
						}
		case 3:{
					     while ( USART_GetFlagStatus(USART3, USART_FLAG_RXNE) == RESET);
						      return (uint8_t)USART_ReceiveData(USART3);
						}
	}
	return 1;	//Error 
}
/*----------------------------------------------------------------------------------*/


/**
Functions sends a single char over USART
*/
void ConnectionUSART::SendData(unsigned char Data)
{
	
	switch(Port)
	{
		case 1:{
							assert_param(IS_USART_ALL_PERIPH(USART1));
  						USART1->DR = (Data & (uint16_t)0x01FF);
					}break;
		case 2:{
							assert_param(IS_USART_ALL_PERIPH(USART2));
  						USART2->DR = (Data & (uint16_t)0x01FF);;
					}break; 
		case 3:{
							assert_param(IS_USART_ALL_PERIPH(USART3));
  						USART3->DR = (Data & (uint16_t)0x01FF);
					}break;
	}
 
}
/*----------------------------------------------------------------------------------*/

 
/**
sends a string(char array) over USART
*/
void ConnectionUSART::SendData(const char *s)
{
		switch(Port)
		{
			case 1:{
							assert_param(IS_USART_ALL_PERIPH(USART1));
					 
					    while(*s)
					    {
					        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
					        USART_SendData(USART1, *s++);
					    }
						}
				case 2:{
							assert_param(IS_USART_ALL_PERIPH(USART2));
					 
					    while(*s)
					    {
					        while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
					        USART_SendData(USART2, *s++);
					    }
						}
					case 3:{
							assert_param(IS_USART_ALL_PERIPH(USART3));
					 
					    while(*s)
					    {
					        while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
					        USART_SendData(USART3, *s++);
					    }
						}
		}
}
